<template>
	<u-popup :show="visible" :safeAreaInsetBottom="false" mode="bottom" bgColor="transparent">
		<view class="handBoard" @touchmove.stop.prevent>
			<view class="handBoard-options">
				<view class="handBoard-options-btn" @click="cancel">取消</view>
				<view class="handBoard-options-btn" @click="clear">重签</view>
				<view class="handBoard-options-btn" @click="confirm">确认</view>
			</view>
			<view class="handBoard-container">
				<canvas @touchstart="handleTouch" @touchmove="handleMove" @touchend="handleEnd" class="my-canvas"
					type="2d" canvas-id="myCanvas" id="myCanvas" ref="myCanvas"></canvas>
				<canvas :style="canvasStyle" style="position: absolute;" canvas-id="rotateCanvas" />
			</view>
		</view>

	</u-popup>
</template>

<script lang="ts" setup>
	const emit = defineEmits(['cancel', 'success'])
	const $instance = ref(getCurrentInstance()!.proxy)
	const visible = ref(false)
	const isDrawing = ref(false); // 是否正在绘制
	const ctx = ref() // 画布渲染上下文
	// 记录最新一次绘制的坐标
	const position = reactive({
		x: 0,
		y: 0
	})
	const canvasStyle = computed(() => {
		return {
			width: '100%',
			height: uni.$u.getPx('400rpx') + 'px'
		}
	})
	const drawBackground = () => {
		// 创建白色矩形背景板
		ctx.value.fillStyle = "#fff"
		ctx.value.fillRect(0, 0, ctx.value.canvas.width, ctx.value.canvas.height)
	}

	// 开始绘制
	const handleTouch = (e: any) => {
		isDrawing.value = true
		// 获取当前点的坐标
		const x = e.touches[0].x;
		const y = e.touches[0].y;
		position.x = x;
		position.y = y;
	}

	const handleMove = (e: any) => {
		if (!isDrawing.value) return;
		const x = e.touches[0].x;
		const y = e.touches[0].y;
		// beginPath() 新建一条路径，生成之后，图形绘制命令被指向到路径上生成路径。
		ctx.value.beginPath();
		// moveTo(x,y) 将笔触移动到指定的坐标 x 以及 y 上。
		ctx.value.moveTo(position.x, position.y);
		// lineTo(x, y) 绘制一条从当前位置到指定 x 以及 y 位置的直线。
		ctx.value.lineTo(x, y);
		// stroke() 使用描边通过线条来绘制当前路径,不需要填充闭合路径
		ctx.value.stroke();
		position.x = x;
		position.y = y;
	}

	const handleEnd = (e: any) => {
		isDrawing.value = false
	}

	// 清除签名
	const clear = () => {
		ctx.value.clearRect(0, 0, ctx.value.canvas.width, ctx.value.canvas.height)
		drawBackground()
	}

	// 确认签名生成图片
	const confirm = () => {
		// 生成图片
		uni.canvasToTempFilePath({
			canvasId: 'myCanvas',
			fileType: 'png',
			quality: 1, //图片质量
			success: (res) => {
				// 在H5平台下，tempFilePath 为 base64
				let canvasContext = uni.createCanvasContext('rotateCanvas', this)
				let width = uni.$u.getPx('400rpx')
				let height = uni.$u.getPx('750rpx')
				canvasContext.translate(height / 2, width / 2)
				canvasContext.rotate(-90 * Math.PI / 180);
				canvasContext.drawImage(res.tempFilePath, -width / 2, -height / 2, width, height)
				/* 绘制水印 */
				canvasContext.rotate(90 * Math.PI / 180);
				canvasContext.translate(-height / 2, -width / 2)
				let text = '万言国学';
				canvasContext.font = `${uni.$u.getPx('28rpx')}px Arial`;
				canvasContext.fillStyle = 'rgba(0, 0, 0, 0.1)';
				canvasContext.setTextBaseline("middle");
				canvasContext.setTextAlign('center');
				/* 水印end */
				// 旋转并重复绘制水印文本
				for (let x = 0; x < height; x += 50) {
					for (let y = 0; y < width; y += 50) {
						canvasContext.save();
						canvasContext.translate(x, y);
						canvasContext.rotate(Math.PI / 4);
						canvasContext.fillText(text, 0, 0);
						canvasContext.restore();
					}
				}
				canvasContext.draw(false, (data) => {
					// 将之前在绘图上下文中的描述（路径、变形、样式）画到 canvas 中
					uni.canvasToTempFilePath({
						// 把当前画布指定区域的内容导出生成指定大小的图片。在 draw() 回调里调用该方法才能保证图片导出成功。
						canvasId: 'rotateCanvas',
						fileType: 'png',
						quality: 1, //图片质量
						success(result) {
							emit('success', result.tempFilePath)
							visible.value = false
						}
					}, $instance.value)
				});
			},
			fail: (res) => {
				console.log(res)
			}
		})
	}
	const cancel = () => {
		visible.value = false
		emit('cancel')
	}
	const open = () => {
		visible.value = true
		nextTick(() => {
			const query = uni.createSelectorQuery()
			query.select('#myCanvas')
				.fields({ node: true, size: true }, () => { })
				.exec((res) => {
					// Canvas 对象
					const canvas = res[0].node;
					// 渲染上下文
					ctx.value = canvas.getContext('2d')
					// 设置绘制属性
					ctx.value.strokeStyle = '#000';
					ctx.value.lineWidth = 2;
					drawBackground()
				})
		})
		return
	}
	defineExpose({
		open
	})
</script>

<style lang="scss" scoped>
	.handBoard {
		position: relative;
		display: flex;
		/* flex-direction: column; */
		height: 100vh;
		background: #ffffff;

		&-options {
			position: relative;
			z-index: 2;
			padding: 20rpx;
			display: flex;
			flex-direction: column;
			justify-content: center;
			background: #ffffff;
			box-shadow: 2rpx 0rpx 12rpx 2rpx rgba(229, 229, 229, 0.4);

			&-btn {
				width: 56rpx;
				height: 132rpx;
				background: var(--themeColors);
				font-weight: 400;
				font-size: 26rpx;
				color: #FFFFFF;
				line-height: 36rpx;
				border-radius: 8rpx;
				display: flex;
				align-items: center;
				justify-content: center;
				writing-mode: vertical-rl;
				/* 竖直方向，从右到左 */
				text-orientation: sideways;

				/* 保持文字直立 */
				&:nth-child(n+2) {
					margin-top: 20rpx;
				}
			}
		}

		&-container {
			width: calc(100% - 96rpx);
			box-sizing: border-box;
			z-index: 1;

			.my-canvas {
				position: relative;
				width: 100%;
				height: 100%;
				background-color: #fff;
			}
		}
	}

</style>
